<template>
  <div class="container">
    <el-tabs v-model="activeName" type="border-card">
      <el-tab-pane name="first" label="轨枕视图" >
        <div class="canvas-box">
          <canvas v-show="activeName == 'first'" ref="canvas" id="canvas" class="canvas"></canvas>
        </div>
        <div class="mark-box"> {{ this.timeValue }} / {{this.maxTimeValue}}</div>
      </el-tab-pane>
      <el-tab-pane name="second" label="轨枕图片" style="overflow: hidden">
        <div class="picture-box" :style="moveStyle(timeValue)" style="display: flex; flex-direction: row;">
          <div class="picture-index" v-for="item in pictureData" :key="item.right" style="display: flex; flex-direction: column; width: 202.1px; height: 409.6px;">
            <image-preview v-show="activeName == 'second'" :src="item.left" width="202.1px" height="204.8px" rotationAngle="270"></image-preview>
            <image-preview v-show="activeName == 'second'" :src="item.right" width="202.1px" height="204.8px" rotationAngle="270"></image-preview>
          </div>
        </div>
        <div class="mark-box"> {{ this.timeValue }} / {{this.maxTimeValue}}</div>
      </el-tab-pane>
    </el-tabs>
    <div class="timeline-box">
      <el-slider v-model="timeValue" :max="maxTimeValue" :min="minTimeValue" @change="changeTimeValue"></el-slider>
    </div>
    <div class="controls">
      <el-button :disabled="isAnimating" @click="backStep">倒退</el-button>
      <el-button :disabled="isAnimating" @click="startAnimation">播放</el-button>
      <el-button :disabled="!isAnimating" @click="pauseAnimation">暂停</el-button>
      <el-button :disabled="isAnimating" @click="goStep">前进</el-button>
    </div>
  </div>
</template>

<script>
import {
  drawGuardRail,
  drawTrack,
  drawTrackCrossingLeftUp,
  drawTrackCrossingRightDown,
  drawTrackCrossingLeftDown,
  drawTrackCrossingRightUp,
  drawTrackSleeper,
  drawTrackPointRight, drawTrackPointLeft,
} from './rail2'
import {querySleeperlist, querySleeperMiniMaxiPixelNoData} from "@/api/system/sleeper";
import {FixedLengthQueue} from "@/utils/queue";
import {drawBoxMid, drawBoxUp, drawPillar, drawSignal} from "./rail2";

export default {
        name: 'CanvasTrack',
        props:{
          // 数量限制
          lineNo: {
            type: Number,
            default: 1,
          },
        },
        watch:{
          lineNo: {
            handler(val) {
              if (val) {
                this.queryParams.lineNo = val
                this.querySleeperParams.lineNo = val
                this.initData()
              }
            },
            deep: true,
            immediate: true
          }
        },
        data() {
            return {
              // tab 切换
                activeName: 'first',
                // 画布
                canvas: null,
                // 画布 高度
                canvasHeight: 660,
                // 画布 宽度
                canvasWidth: null,
                // 画布内容
                canvasContext: null,
                // 轨枕队列
                sleeperQueue: null,
                // 图片队列
              pictureQueue: null,
              // 当前图片index
              pictureIndex: null,
              //图片数据
              pictureData: null,
                keyword: 0,
                // 轨枕分页查询参数
                queryParams: {
                  mark: 'MinMax',
                    lineNo: 1,
                    pixelNo: 0,
                    moveSign: 'ADD',
                    moveNum: 90
                },
              querySleeperParams:{
                 mark: 'MinMax',
                lineNo: 1,
                sleeperNo: null
              },
                // 最小时间
                minTimeValue: 0,
                // 最大时间
                maxTimeValue: 10000,
                // 最小像素
                minPixelNo: null,
                // 最大像素
                maxPixelNo: null,
                //当前最大像素
                currentMaxPixelNo: null,
                //上一个时间
                preTimeValue: 0,
                // 当前时间
                timeValue: 0,
                // 动画
                isAnimating: false,
                // 动画标识
                animationId: null,
                // 播放速度
                playbackSpeed: 1, // 默认播放速度为1倍速
              // 请求数据间隔
                dataRequestInterval: 300,
              // 缩放倍数
                num: 10,
              // step
              step: 1000
            }
        },
        methods: {
          // 初始化布局
            initCanvas() {
                this.canvasWidth = this.$refs.canvas.parentElement.clientWidth; // 获取父容器宽度
                this.animationId = null
                this.canvas = new fabric.Canvas('canvas', {
                    width: this.canvasWidth,
                    height: this.canvasHeight,
                    selection: false,
                    selectable: false, // 禁止选择和拖动
                    evented: false,     // 禁止触发事件
                  lockMovementX: true,
                  lockMovementY: true
                })
            },
          // 清除画布所有的内容
            clearAll() {
                this.canvas.clear().renderAll()
            },
            // 渲染轨枕
          renderSleeper(){
                this.clearAll()
                drawTrack(this.canvas, 0, 220, this.maxPixelNo, 220, 15)
                drawTrack(this.canvas, 0, 420, this.maxPixelNo, 420, 15)
                var step = this.timeValue
                let preSleeperPixelNo = 0;
                this.sleeperQueue.getAllElements().forEach(sleeper=>{
                    const x = this.getIntValue(sleeper.pixelNo,this.num,'divide') - step
                  // 尖轨尖
                  if(sleeper.isSwitch && sleeper.isSwitch === '2'){
                    if(sleeper.switchDirection === 'L'){
                      drawTrackPointRight(this.canvas, x, 225, x, 425, 12, '#303030', this.timeValue)
                    }else{
                      drawTrackPointLeft(this.canvas, x, 225, x, 425, 12, '#303030', this.timeValue)
                    }
                  }else{
                    drawTrackSleeper(this.canvas, x, 160, x, 500, 25, '#303030', this.timeValue,sleeper)
                  }

                  if(sleeper.sleeperNo === 10){
                     drawSignal(this.canvas, x, 550, x, 630, 25, '#303030', this.timeValue,sleeper)
                      drawBoxUp(this.canvas, x, 60, x, 100, 25, '#303030', this.timeValue,sleeper)
                      drawBoxMid(this.canvas, x, 300, x, 360, 25, '#303030', this.timeValue,sleeper)
                  }


                  if((sleeper.sleeperNo-5) % 85 === 0){
                    drawPillar(this.canvas,x,560,5)
                  }

                  // 岔道
                  if(sleeper.isSwitch && sleeper.isSwitch === '1'){
                    const switchStartPixelNo = this.getIntValue(sleeper.startPixelNo,this.num,'divide') - step
                    const switchEndPixelNo = this.getIntValue(sleeper.endPixelNo,this.num,'divide') - step
                    if(sleeper.switchDirectionDu === 'D' && sleeper.switchDirectionLr === 'L'){
                      drawTrackCrossingLeftUp(this.canvas,switchStartPixelNo,switchEndPixelNo)

                    } else if(sleeper.switchDirectionDu === 'U' && sleeper.switchDirectionLr === 'L'){
                      drawTrackCrossingRightUp(this.canvas,switchStartPixelNo,switchEndPixelNo)
                    }else if(sleeper.switchDirectionDu === 'D' && sleeper.switchDirectionLr === 'R'){
                      drawTrackCrossingLeftDown(this.canvas,switchStartPixelNo,switchEndPixelNo)
                    }else if(sleeper.switchDirectionDu === 'U' && sleeper.switchDirectionLr === 'R'){
                      drawTrackCrossingRightDown(this.canvas,switchStartPixelNo,switchEndPixelNo)
                    }
                  }
                  // 护轨
                  if(sleeper.isGuardRail && sleeper.isGuardRail === '1'){
                    drawGuardRail(this.canvas,preSleeperPixelNo,320,x,320,15 )
                  }
                  preSleeperPixelNo = x;
                })
                this.preTimeValue = this.timeValue
                this.canvas.renderAll()
            },
          // 初始化数据
            async initData() {
                this.initPictureQueue()
                this.sleeperQueue = new FixedLengthQueue(this.queryParams.moveNum * 2);
                const { rows: res } = await querySleeperMiniMaxiPixelNoData(this.queryParams)
                this.minPixelNo = this.getIntValue(res[0].pixelNo,this.num,'divide')
                this.maxPixelNo = this.getIntValue(res[1].pixelNo,this.num,'divide') - this.minPixelNo - this.canvasWidth > 0 ? this.getIntValue(res[1].pixelNo,this.num,'divide') - this.canvasWidth : this.getIntValue(res[1].pixelNo,this.num,'divide')
                this.currentMaxPixelNo = this.minPixelNo
                this.minTimeValue = this.minPixelNo
                this.timeValue = this.minTimeValue
                this.maxTimeValue = this.getIntValue(res[1].pixelNo,this.num,'divide') - this.minPixelNo - this.canvasWidth > 0 ? this.getIntValue(res[1].pixelNo,this.num,'divide') - this.canvasWidth : this.getIntValue(res[1].pixelNo,this.num,'divide')
                var param = {
                    moveSign: 'add',
                    moveNum: this.queryParams.moveNum,
                    startPixelNo: this.minPixelNo,
                    endPixelNo: this.maxPixelNo
                }
                this.$emit('changeTime', param)
                this.clearAll()
                this.draw()
                this.preTimeValue = 0
            },
          //初始化图片队列
          initPictureQueue(){
              this.pictureQueue = new FixedLengthQueue(10);
              this.pictureIndex = 10
              for(let i = 1;i<=10;i++){
                let data = {
                  left: 'http://127.0.0.1:17024/data/L/L'+i+'.jpg',
                  right: 'http://127.0.0.1:17024/data/R/R'+i+'.jpg'
                }
                this.pictureQueue.enqueue(data)
              }
              this.pictureData = this.pictureQueue.getAllElements()
            },
          // 画图
            async draw() {
                this.queryParams.pixelNo = this.currentMaxPixelNo
                const { rows: data } = await querySleeperlist(this.queryParams)
                if(data){
                    this.currentMaxPixelNo = this.getIntValue(data[data.length - 1 ].pixelNo,this.num,'divide')
                    data.forEach(sleeper=>{
                        this.sleeperQueue.enqueue(sleeper)
                    })
                }
                this.renderSleeper()
                this.canvas.renderAll()
            },
          // 搜索
            async search() {
                this.pauseAnimation()
                this.timeValue = parseInt(this.keyword)
                this.queryParams.pixelNo = this.keyword
                const { rows: data } = await querySleeperlist(this.queryParams)
                if(data){
                    this.currentMaxPixelNo = parseInt(data[data.length - 1 ].pixelNo)
                    this.sleeperQueue.clearAll()
                    data.forEach(sleeper=>{
                        this.sleeperQueue.enqueue(sleeper);
                    })
                }
                this.renderSleeper()
            },
          // 前进和后退
          goStep(){
              console.log('go')
            this.pauseAnimation()
            if(this.timeValue!==this.maxTimeValue){
              let width = parseInt(this.canvasWidth/3)
              this.timeValue = this.timeValue + width < this.maxTimeValue ? this.timeValue + width : this.maxTimeValue
              console.log(this.queryParams.pixelNo)
              this.changeTimeValue()
            }
          },
          //后退
          backStep(){
            console.log('back')
            this.pauseAnimation()
            if(this.timeValue!==this.minTimeValue){
              let width = parseInt(this.canvasWidth/3)
              this.timeValue = this.timeValue - width > this.minTimeValue ? this.timeValue - width : this.minTimeValue
              console.log(this.queryParams.pixelNo)
              this.changeTimeValue()
            }
          },
          // 时间戳改变事件
            async changeTimeValue(){
                var oldAnimateStatus = this.isAnimating
                //this.pauseAnimation()
                this.queryParams.pixelNo =  this.getIntValue(this.timeValue,this.num,'mutilple')
              var param = {
                moveSign: 'add',
                moveNum: this.queryParams.moveNum,
                startPixelNo: this.minPixelNo,
                endPixelNo: this.maxPixelNo
              }
              this.$emit('changeTime', param)
              this.changeImage(this.timeValue)
                const { rows: data } = await querySleeperlist(this.queryParams)
                if(data){
                    this.currentMaxPixelNo = this.getIntValue(data[data.length - 1 ].pixelNo,this.num,'divide')
                    this.sleeperQueue.clearAll()
                    data.forEach(sleeper=>{
                        this.sleeperQueue.enqueue(sleeper);
                    })
                }
                this.renderSleeper()
                if(oldAnimateStatus){
                    this.startAnimation()
                }
            },
          // 改变图片事件
          changeImage(val){
              this.moveStyle(val)
            this.pictureQueue.clearAll()
            let index  = parseInt(this.timeValue/202)+1;
            for(let i = index;i<=10+index;i++){
              let data = {
                left: 'http://127.0.0.1:17024/data/L/L'+i+'.jpg',
                right: 'http://127.0.0.1:17024/data/R/R'+i+'.jpg'
              }
              this.pictureQueue.enqueue(data)
            }
            this.pictureData = this.pictureQueue.getAllElements()
          },
          // style 变化
          moveStyle(val) {
              let moveIndex = val % 202
            return { transform: `translateX(-${moveIndex}px)` };
          },
          // 开始动画
            startAnimation() {
                if (!this.isAnimating) {
                    this.isAnimating = true
                    this.animateFrame()
                }
            },
            // 暂停
            pauseAnimation() {
                if (this.isAnimating) {
                    clearInterval(this.animationId)
                    this.isAnimating = false
                }
            },
            // 动画
          animateFrame() {
              if (!this.isAnimating) return;

              this.timeValue += this.playbackSpeed; // 使用当前倍速更新时间值
              if (this.timeValue >= this.maxTimeValue) { // 假设100为最大值
                this.pauseAnimation(); // 先暂停
                this.resetFrame();
                return;
              }

              // 新的逻辑：每过一定的时间值，获取新数据
              if ((this.timeValue % this.dataRequestInterval) === 0) {
                this.changeTimeValue();
              } else {
                this.changeImage(this.timeValue)
                this.renderSleeper();
              }

              // 请求下一帧动画
              this.animationId = requestAnimationFrame(() => {
                this.animateFrame();
              });
            },
            resetFrame(){
                this.timeValue = this.minTimeValue
                this.renderSleeper()
            },
            // 处理页面大小变化
            handleResize() {
                this.canvasWidth = this.$refs.canvas.parentElement.clientWidth;
                this.canvas.setWidth(this.canvasWidth)
                this.canvas.renderAll(); // 不管是首次还是后续调整，都需要重新渲染canvas
            },
            // getIntValue(int origin, )
            getIntValue(origin,p,type){
                if(type === 'divide'){
                    return parseInt(origin / p)
                }else{
                    return parseInt(origin * p)
                }
            },
        },
        created() {
            this.initCanvas()
            this.initData()
          //this.draw123()
            this.handleResize()
            window.addEventListener('resize', this.handleResize);
        },
        mounted() {
            this.initCanvas()
            this.initData()
         // this.draw123()
            this.handleResize()
            window.addEventListener('resize', this.handleResize);
        },
        destroyed() {
            window.removeEventListener('resize', this.handleResize);
        },
    }
</script>

<style scoped>
  .canvas-box{
    width: 100%;
    height: 92%;
    border: #999999 1px solid;
    border-radius: 8px;
  }
  .canvas{
    width: 100%;
    height: 100%;
  }
  .timeline-box {
    padding: 20px 0;
    width: 100%;
  }
  /* ...原有样式... */
  .controls {
    display: flex;
    justify-content: center;
    margin-bottom: 20px;
    .image{
      margin: 0 10px;
      width: 30px;
      height: 30px;
    }
  }
  .mark-box{
    font-size: 18px;
    font-weight: bold;
  }
</style>
